/**
 * 格式化生成页面的函数方法
 */
const forMatVueMethods = (exportDefault, lowCodePageJson) => {
  
  const methods = [];

  // 记录同步函数
  let originFnContent = ""

  Object.keys(exportDefault.methods || {}).forEach(v => {
    let targetFn = getMethodContent(exportDefault.methods[v])
    if(targetFn.asyncFn){
      // 生成异步函数
      methods.push(forMatAsyncMethodNode(v, targetFn.content, targetFn.paramNames))
    }else{
      // 生成同步函数
      originFnContent += `
        this.${v} = (${targetFn.paramNames.join(',')}) => {
          ${targetFn.content}  
        }
        
      `

      // 同时往模型视图中生成自定义变量用于承载自定义函数名称，还要挂载到xPage的初始化方法中
      lowCodePageJson.viewModel[v] = {
        name: v,
        label: v,
        description: '自定义变量',
        dataType: {
          type: 'object',
          list: false
        },
        defaultValue: "",
        vmDataType: "customData"
      }
    }
  })

  // 表示插入了同步函数 (因为最终还是要靠异步方法去生成同步方法)
  if(originFnContent){
    methods.push(forMatAsyncMethodNode("synchronizationFunction", originFnContent, [], '生成同步函数'))
  }

  return methods;
}


/**
 * 获取当前函数执行体中的代码
 */
const getMethodContent = (fn) => {
  let javaScriptContent = fn.toString();
  // 是否是异步函数
  let asyncFn = javaScriptContent.startsWith('async') ? true : false;
  // 去掉function关键字
  javaScriptContent = javaScriptContent.replace(/function\s*\w*\s*\(/, '');

  // 使用正则表达式提取函数参数名称
  var paramNames = [];
  var paramMatch = javaScriptContent.match(/\(([^)]*)\)/); // 匹配函数参数列表

  if (paramMatch && paramMatch[1]) {
    // 分割参数列表并去除空格
    paramNames = paramMatch[1].split(',').map(param => param.trim()).filter(param => param);
  }

  let startIndex = javaScriptContent.indexOf('{');
  let endIndex = javaScriptContent.lastIndexOf('}');

  return {
    asyncFn,
    paramNames,
    content: javaScriptContent.substring(startIndex + 1, endIndex)
  };
}


/**
 * 
 * @returns 返回当前函数方法的pageJson 【低代码异步方法】
 * name 函数名称
 * javaScriptContent 函数体
 * params 入参
 * label 函数中文名称
 */
const forMatAsyncMethodNode = (name, javaScriptContent = "", params, label) => {
  const startNodeId = dynamicUuid("node_start_");
  const endNodeId = dynamicUuid("node_end_");
  const javaScriptNode = dynamicUuid("node_javaScript_");

  // 生成入参
  let inputs = [];
  params.forEach(v=> {
    inputs.push({
      name: v,
      label: v,
      dataType:{
          list: false,
          type: "text",
          entity:""
      },
      defaultVal:""
    })
  })

  return {
    config: {
      version: "1.0.0",
      inputs: inputs,
      flows: [
        {
          origin: javaScriptNode,
          destination: endNodeId,
          type: "normal"
        },
        {
          origin: startNodeId,
          destination: javaScriptNode,
          type: "normal"
        }
      ],
      linkList: [
        {
          endId: endNodeId,
          startId: javaScriptNode,
          points: [180, 264.5, 180, 330, 180, 395.5],
          meta: {},
          category: "Normal"
        },
        {
          endId: javaScriptNode,
          startId: startNodeId,
          points: [180, 114.5, 180, 164, 180, 213.5],
          meta: {},
          category: "Normal"
        }
      ],
      nodeList: [
        {
          id: startNodeId,
          meta: {
            name: "start",
            type: "start",
            randomId: 1675330080059
          },
          coordinate: ["180", "89"]
        },
        {
          id: endNodeId,
          meta: {
            name: "end",
            type: "end",
            designDescription: "",
            randomId: 1675330081781
          },
          coordinate: ["180", "421"]
        },
        {
          id: javaScriptNode,
          meta: {
            name: "javaScript",
            type: "javaScript",
            condition: javaScriptContent
          },
          coordinate: ["180", "239"]
        }
      ],
      nodes: [{
        id: startNodeId,
        type: "start"
      },
      {
        id: endNodeId,
        type: "end",
        config: {}
      },
      {
        id: javaScriptNode,
        type: "javaScript",
        config: {
          content: javaScriptContent
        }
      }],
      output: {
        dataType: {
          type: "void",
          entity: "",
          list: false
        }
      },
      typeParameters: []
    },
    description: "",
    label: label || name,
    name: name,
    runType: "clientFlow",
    type: "clientFlowAction"
  }
}